from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.utils import timezone

class CustomUserManager(BaseUserManager):
    def create_user(self, phone, nickname, password=None, **extra_fields):
        if not phone:
            raise ValueError('The Phone field must be set')
        user = self.model(
            phone=phone,
            nickname=nickname,
            **extra_fields
        )
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, phone, nickname, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        return self.create_user(phone, nickname, password, **extra_fields)

class User(AbstractBaseUser):
    phone = models.CharField(max_length=11, unique=True)
    nickname = models.CharField(max_length=50, null=True, blank=True, verbose_name='昵称')
    id_card = models.CharField(max_length=18, unique=True, null=True, blank=True, verbose_name='身份证号')
    password = models.CharField(max_length=128)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    date_joined = models.DateTimeField(auto_now_add=True)
    account = models.IntegerField(default=0, verbose_name='账户余额')

    def __str__(self):
        return self.phone

    def clean(self):
        super().clean()
        if self.id_card:
            # 验证身份证号格式
            if not self.id_card.isdigit() or len(self.id_card) != 18:
                raise ValidationError({'id_card': '请输入18位数字的身份证号'})
            # 验证身份证号的有效性
            if not self.validate_id_card(self.id_card):
                raise ValidationError({'id_card': '无效的身份证号'})

    def validate_id_card(self, id_card):
        """验证身份证号的有效性"""
        if len(id_card) != 18:
            return False
        
        # 验证前17位是否都是数字
        if not id_card[:-1].isdigit():
            return False
            
        # 验证最后一位校验码
        weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
        check_codes = '10X98765432'
        
        sum_product = sum(int(id_card[i]) * weights[i] for i in range(17))
        check_code = check_codes[sum_product % 11]
        
        return check_code == id_card[-1]

    objects = CustomUserManager()

    USERNAME_FIELD = 'phone'
    REQUIRED_FIELDS = ['nickname', 'id_card']

    def has_perm(self, perm, obj=None):
        return self.is_superuser

    def has_module_perms(self, app_label):
        return self.is_superuser

    class Meta:
        db_table = 'users'
        verbose_name = '用户'
        verbose_name_plural = '用户'

class Category(models.Model):
    name = models.CharField(max_length=100, verbose_name='分类名称')
    parent = models.ForeignKey(
        'self',
        null=True,
        blank=True,
        on_delete=models.CASCADE,
        related_name='subcategories',
        verbose_name='父分类'
    )
    created_at = models.DateTimeField(default=timezone.now, verbose_name='创建时间')

    class Meta:
        db_table = 'categories'
        verbose_name = '分类'
        verbose_name_plural = '分类'
        ordering = ['name']

    def __str__(self):
        full_path = [self.name]
        parent = self.parent
        while parent is not None:
            full_path.append(parent.name)
            parent = parent.parent
        return ' -> '.join(full_path[::-1])

class Product(models.Model):
    title = models.CharField(max_length=200, verbose_name='标题')
    is_displayed = models.BooleanField(default=True, verbose_name='是否展示')
    category = models.ForeignKey(
        Category,
        on_delete=models.CASCADE,
        related_name='products',
        verbose_name='分类'
    )
    publisher = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='products',
        verbose_name='联系人'
    )

    description = models.TextField(verbose_name='描述')
    price = models.IntegerField(default=0, verbose_name='价格')
    image = models.ImageField(upload_to='product_images/', null=True, blank=True, verbose_name='商品图片')
    created_at = models.DateTimeField(default=timezone.now, verbose_name='发布时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    def __str__(self):
        publisher_name = self.publisher.nickname if self.publisher.nickname else '未知用户'
        return f"{self.title} - {publisher_name}"

    def image_url(self):
        if self.image:
            return self.image.url
        return '/static/images/default-product.png'  # 默认图片

    class Meta:
        db_table = 'products'
        verbose_name = '商品'
        verbose_name_plural = '商品'

    def __str__(self):
        return f"{self.title} ({self.category.name})"
